﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Extented.UI.Core.Native
{
    [DebuggerStepThrough]
    public class Locker : IDisposable
    {
        int lockCount;
        public bool IsLocked { get { return lockCount > 0; } }
        public event EventHandler Unlocked;
        public Locker LockOnce()
        {
            if (!IsLocked)
                Lock();
            return this;
        }
        public Locker Lock()
        {
            lockCount++;
            return this;
        }
        public void Unlock()
        {
            if (IsLocked)
            {
                lockCount--;
                if (!IsLocked)
                    RaiseOnUnlock();
            }
        }
        public void Reset()
        {
            lockCount = 0;
        }
        public void DoLockedAction(Action action)
        {
            Lock();
            try
            {
                action();
            }
            finally
            {
                Unlock();
            }
        }
        public void DoIfNotLocked(Action action)
        {
            if (!IsLocked)
                action();
        }
        public void DoLockedActionIfNotLocked(Action action)
        {
            DoIfNotLocked(() => DoLockedAction(action));
        }
        public void DoIfNotLocked(Action action, Action lockedAction = null)
        {
            if (!IsLocked)
            {
                action();
            }
            else
            {
                if (lockedAction != null)
                    lockedAction();
            }
        }
        void RaiseOnUnlock()
        {
            if (Unlocked != null)
                Unlocked(this, EventArgs.Empty);
        }
        #region for using directive usage
        void IDisposable.Dispose()
        {
            Unlock();
        }
        #endregion
        #region implicit convert to bool
        public static implicit operator bool(Locker locker)
        {
            return locker.IsLocked;
        }
        #endregion
    }
}
